import bean.Corporation;
import bean.Person;
import context.CustomApplicationEvent;

import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.support.BeanDefinitionReader;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.*;

import java.util.*;

public class Demo {
    private Resource resource;
    // DefaultListableBeanFactory类实现了bean定义注册表（BeanDefinitionRegistry）接口
    private DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
    private BeanDefinitionReader reader;
    private AbstractApplicationContext context;
    
    @Before
    public void setUp() {
        // 加载bean工厂，注意bean工厂只有获取bean的功能
        {
            resource = new ClassPathResource("spring-config.xml");
            // Bean定义注册表（BeanDefinitionRegistry）
            reader = new XmlBeanDefinitionReader(factory);
            // 使用Bean定义读取器从资源中加载bean定义
            reader.loadBeanDefinitions(resource);
        }
        // 加载应用程序上下文
        {
            // BeanFactory是ApplicationContext继承的接口之一，后者具有前者的所有功能
            context = new ClassPathXmlApplicationContext("/spring-config.xml");
        }
    }
    
    @Test
    public void testFactory() {
        Date now = (Date) factory.getBean("now");
        System.out.println("当前系统默认时区时间：" + now);
        Person person1 = (Person) factory.getBean("person1");
        System.out.println(person1);
        Person person2 = (Person) factory.getBean("person2");
        System.out.println(person2);
        Corporation corporation = (Corporation) factory.getBean("corporation");
        String[] departments = corporation.getDepartments();
        System.out.println("该公司一共有" + departments.length + "个部门");
        System.out.println(departments[0]);
        System.out.println(departments[1]);
        System.out.println(departments[2]);
        System.out.println(departments[3]);
        List<String> positions = corporation.getPositions();
        System.out.println("每个部门下分" + positions.size() + "个职位");
        System.out.println(positions.get(0));
        System.out.println(positions.get(1));
        System.out.println(positions.get(2));
        Map<Integer, String> employees = corporation.getEmployees();
        System.out.println("公司一共有" + employees.size() + "名员工");
        Set<Map.Entry<Integer, String>> entrySet = employees.entrySet();
        for (Map.Entry<Integer, String> entry : entrySet) {
            System.out.print(entry.getKey());
            System.out.println("：" + entry.getValue());
        }
    }
    
    @Test
    public void testContext() {
        Person person3 = (Person) context.getBean("person3");
        System.out.println(person3);
        System.out.println(context.getMessage("msg", new Object[] { "你", "spring依赖注入" }, Locale.CHINA));
        System.out.println(context.getMessage("info", new String[] { "当前用户" }, Locale.CHINA));
        // 发布事件
        context.publishEvent(new CustomApplicationEvent(this));
        // AbstractApplicationContext类实现了Closeable接口，此类实例应当在使用完毕后调用close方法关闭
        context.close();
    }
}
